package com.zygh.lz.controller.app;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.zygh.lz.dao.GpsMapper;
import com.zygh.lz.dao.PatrolrecordMapper;
import com.zygh.lz.dao.SignMapper;
import com.zygh.lz.entity.Gps;
import com.zygh.lz.entity.GpsHistory;
import com.zygh.lz.entity.Patrolrecord;
import com.zygh.lz.entity.Sign;
import com.zygh.lz.entity.vo.CoordinateData;
import com.zygh.lz.entity.vo.Trajectory;
import com.zygh.lz.service.GpsService;
import com.zygh.lz.service.PatrolrecordService;
import com.zygh.lz.service.impl.GpsHistoryService;
import com.zygh.lz.stapprove.*;
import com.zygh.lz.util.CoordinateTransform;
import com.zygh.lz.util.DistanceUtil;
import com.zygh.lz.vo.ResultBean;
import com.zygh.lz.vo.ResultBeans;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Api(tags = "APP上传GPS", description = "AppGPSController")
@RestController
@Validated
public class AppGPSController {
    @Resource
    private GpsService gpsService;
    @Resource
    private PatrolrecordService patrolrecordService;
    @Resource
    private GpsMapper gpsMapper;
    @Resource
    private SignMapper signMapper;

    @Resource
    private PatrolrecordMapper patrolrecordMapper;
    @Resource
    private GpsHistoryService gpsHistoryService;


    private final Logger log = LoggerFactory.getLogger("GPSServer");



    /*@ApiOperation("实时上传gps")
    @PostMapping("addGps")
    @Async("asyncServiceExecutor")
    public void addGps(@Valid Gps gps, @RequestBody(required = false) InBean inBean) {

        JSONObject jsonObject = inBean.convertObj(JSONObject.class);
        Patrolrecord patrolrecord = new Patrolrecord();
        int sysPatrolRecordId = Integer.parseInt(jsonObject.getString("sysPatrolRecordId"));
        patrolrecord.setSysPatrolRecordId(sysPatrolRecordId);
        patrolrecord.setPatrolRecordEndtime(new Date());
        patrolrecordMapper.updateByPrimaryKeySelective(patrolrecord);
        Map<String, String> map = TurnJsonUtil.GPSToJSON(jsonObject.getString("coordinate"));
        if (map.size() == 0) {
            return;
        }
        gps.setTotal(Integer.valueOf(map.get("total")))
                .setDistance(Double.parseDouble(map.get("distance")))
                .setCoordinate(map.get("collect"))
                .setSpeed(map.get("speed"))
                .setDirection(map.get("direction"))
                .setGpsTime(new Date())
                .setSignnum(jsonObject.getString("signNum"))
                .setSysPatrolRecordId(sysPatrolRecordId)
                .setSysStaffId(Integer.parseInt(jsonObject.getString("sysStaffId")))
                .setDistrict(jsonObject.getString("District"))
                .setTown(jsonObject.getString("Town"))
                .setLocationDescribe(jsonObject.getString("LocationDescribe"));

        //   log.info("========================坐标：" + map.get("collect") + "===========================");
        gpsService.addGps(gps);
        //修改巡查记录列表
        patrolrecord.setSysPatrolRecordId(sysPatrolRecordId);
        patrolrecord.setPatrolRecordGps(map.get("collect"));
        patrolrecord.setPatrolRecordEndtime(new Date());
        patrolrecordMapper.updateByPrimaryKeySelective(patrolrecord);

    }*/

    @PostMapping("test")
    public Map<String, String> test(String result) {
        Map<String, String> resultStepout = TurnJsonUtil.GPSToJSONs(result);
        return resultStepout;
    }

    @ApiOperation("实时上传gps")
    @PostMapping("addGps")
    public OutBean addGps(@RequestBody(required = false) InBean inBean) {
        Gps gps = new Gps();
        JSONObject jsonObject = inBean.convertObj(JSONObject.class);
        Integer integer = signMapper.selectCount(Wrappers.<Sign>lambdaQuery().eq(Sign::getState, 1)
                .eq(Sign::getStaffid, jsonObject.getString("sysStaffId")));
        if (integer == 0) {
            ResultBeans resultBeans = ResultUtil.resultBeansSuccess("false");
            return OutBeanUtil.resSuc(resultBeans, inBean);
        }
        Patrolrecord patrolrecord = new Patrolrecord();
        int sysPatrolRecordId = Integer.parseInt(jsonObject.getString("sysPatrolRecordId"));
        patrolrecord.setSysPatrolRecordId(sysPatrolRecordId);
        patrolrecord.setPatrolRecordEndtime(new Date());
        patrolrecordMapper.updateByPrimaryKeySelective(patrolrecord);
        String coordinate = jsonObject.getString("coordinate");
        //log.info("轨迹上传《《《《《《《《《《《《《《《" + jsonObject.getString("sysStaffId"));
        //log.info("APP所有入参：" + jsonObject);
        //log.info("坐标入参：" + coordinate);
        Map<String, String> map = TurnJsonUtil.GPSToJSONs(coordinate);
        //log.info("坐标出参：" + JSON.toJSONString(map));
        if (map.size() == 0) {
            ResultBeans resultBeans = ResultUtil.resultBeansSuccess("true");
            return OutBeanUtil.resSuc(ResultUtil.resultBeansSuccess(resultBeans), inBean);
        }

        //存入原始坐标如果顺丰返回距离为0再计算一次
        List<Trajectory> trajectoryList = new Gson().fromJson(coordinate, new TypeToken<List<Trajectory>>() {
        }.getType());
        StringBuilder sb = new StringBuilder();
        for (Trajectory trajectory : trajectoryList) {
            sb.append(trajectory.getX()).append(",").append(trajectory.getY()).append(",");
        }
        sb.delete(sb.length() - 1, sb.length());
        gps.setOriginal(sb.toString());


        gps.setTotal(Integer.valueOf(map.get("total")))
                .setDistance(Double.parseDouble(map.get("distance")))
                .setCoordinate(map.get("collect"))
                .setGpsTime(new Date())
                .setLocationDescribe(map.get("locationDescribe"))
                .setSignnum(jsonObject.getString("signNum"))
                .setSysPatrolRecordId(sysPatrolRecordId)
                .setSysStaffId(Integer.parseInt(jsonObject.getString("sysStaffId")))
                .setDistrict(jsonObject.getString("District"))
                .setTown(jsonObject.getString("Town"))
                .setLocationDescribe(jsonObject.getString("LocationDescribe"))
                .setDistance(Double.parseDouble(map.get("distance")));
        //   log.info("========================坐标：" + map.get("collect") + "===========================");
        //GpsTest gpsTest = new GpsTest();
        //BeanUtils.copyProperties(gps, gpsTest);

        if (gps.getDistance() < 1) {
            //返回的公里，换算成米
            String collect = DistanceUtil.jq(gps.getOriginal());
            double lic = Double.parseDouble(collect);
            DecimalFormat dub = new DecimalFormat("#0.00");
            String format = dub.format(lic * 1000);
            gps.setDistance(Double.parseDouble(format));
        }

        gpsService.addGps(gps);
        //修改巡查记录列表
        patrolrecord.setSysPatrolRecordId(sysPatrolRecordId);
        patrolrecord.setPatrolRecordGps(map.get("collect"));
        patrolrecord.setPatrolRecordEndtime(new Date());
        patrolrecordMapper.updateByPrimaryKeySelective(patrolrecord);
        ResultBeans resultBeans = ResultUtil.resultBeansSuccess("true");
        return OutBeanUtil.resSuc(ResultUtil.resultBeansSuccess(resultBeans), inBean);
    }


    @Async("asyncServiceExecutor")
    public String transitionGPS(String coordinate) {
        List<CoordinateData> coordinateDataList = new Gson().fromJson(coordinate, new TypeToken<List<CoordinateData>>() {
        }.getType());
        //   System.out.println("============转换坐标系之前：" + coordinateDataList);
        coordinateDataList.forEach(coordinateData -> {
            //转换坐标
            double[] doubles = CoordinateTransform.transformGCJ02ToWGS84(coordinateData.getLongitude(), coordinateData.getLatitude());
            coordinateData.setLongitude(doubles[0]);
            coordinateData.setLatitude(doubles[1]);
        });
        //   System.out.println("============转换坐标系之后：" + coordinateDataList);
        String collect = coordinateDataList.stream().map(c -> c.getLongitude() + "," + c.getLatitude()).collect(Collectors.joining(","));
        return collect;
    }


    @ApiOperation("APP根据人员id和巡查id查询GPS轨迹坐标")
    @PostMapping("selectAllGPSById")
    @ViLog(logType = "1", module = "根据人员id和巡查id查询GPS坐标")
    public OutBean selectAllGPSById(@RequestBody(required = false) InBean inBean) {
        JSONObject jsonObject = inBean.convertObj(JSONObject.class);
        ResultBeans resultBeans = patrolrecordService.selectAllGPSById(Integer.parseInt(jsonObject.getString("staffId")), Integer.parseInt(jsonObject.getString("patrolrecordId")));
        return OutBeanUtil.resSuc(resultBeans, inBean);
    }

    @ApiOperation("PC根据人员id和巡查id查询GPS轨迹坐标")
    @GetMapping("selectTrackById")
    public ResultBean selectTrackById(Integer staffId, Integer patrolrecordId) {
        String resultBeans = patrolrecordService.selectTrackById(staffId, patrolrecordId);
        return ResultUtil.setOK("success", resultBeans);
    }

    @ApiOperation("PC个人轨迹查询")
    @GetMapping("selectTracksById")
    public ResultBean selectTracksById(Integer patrolrecordId) {
        List<Map> resultBeans = patrolrecordService.selectTracksById(patrolrecordId);
        return ResultUtil.setOK("success", resultBeans);
    }


    //批量修改之前gps坐标轨迹
    @GetMapping("vacuate")
    public void vacuate() {
        //没有抽稀过的数据
        List<Patrolrecord> patrolrecords = patrolrecordMapper.findAllByisrarefy();
        patrolrecords.forEach(patrolrecord -> {
            List<Gps> gpsList = gpsMapper.selectGpsByRecords(patrolrecord.getSysStaffId(), patrolrecord.getSysPatrolRecordId());
            String allGps = gpsList.stream().map(x -> x.getGpsX() + "," + x.getGpsY()).collect(Collectors.joining(","));
            String collect = patrolrecordService.vacuateGPS(allGps);
            Gps gps = new Gps();
            gps.setCoordinate(collect);
            gps.setGpsTime(new Date());
            gps.setSysStaffId(patrolrecord.getSysStaffId());
            gps.setSysPatrolRecordId(patrolrecord.getSysPatrolRecordId());
            gpsMapper.insertSelective(gps);
            gpsList.forEach(gps1 -> {
                gpsMapper.deleteByPrimaryKey(gps1.getSysGpsId());
            });
        });

    }

    @ApiOperation("轨迹热力图")
    @GetMapping("selectGpsByTime")
    public List<String> selectGpsByTime(String startTime, String endTime, Integer sectionid, Integer staffId) {
        List<String> list = new ArrayList<>();
        List<Map> gpsSignNum = gpsMapper.findGpsSignNum(startTime, endTime, sectionid, staffId);
        for (int i = 0; i < gpsSignNum.size(); i++) {
            List<Gps> gpsList = gpsMapper.findGpsBySignNum(gpsSignNum.get(i).get("signnum").toString());
            String allGps = gpsList.stream().map(x -> x.getCoordinate()).collect(Collectors.joining(","));
            list.add(allGps);
        }
        return list;
    }

    @ApiOperation("新增")
    @PostMapping("insterGPS")
    public void insterGPS(@RequestBody Gps gps) {
        //gpsService.addGps(gps);
    }

    @ApiOperation("没有纠偏的轨迹标识")
    @GetMapping("findNoAction")
    public List<Map> findNoAction() {
        return gpsHistoryService.findNoAction();
    }

    @ApiOperation("根据标识查询轨迹进行纠偏")
    @GetMapping("findNoActionGPS")
    public List<GpsHistory> findNoActionGPS(String signNum) {
        return gpsHistoryService.findNoActionGPS(signNum);
    }

    @ApiOperation("轨迹测试")
    @GetMapping("testGPS")
    public HashMap<String, Object> testGPS(String signNum) {
        HashMap<String, Object> paramMap = new HashMap<>();
        List<Gps> gps = gpsMapper.testGps(signNum);
        List<Trajectory> trajectoryList = new ArrayList<>();
        for (int i = 0; i < gps.size(); i++) {
            Trajectory trajectory = new Trajectory();
            trajectory.setAccuracy(15);
            trajectory.setType(1);
            trajectory.setIndex(i);
            trajectory.setTime(Long.parseLong(gps.get(i).getDistrict()));
            String coordinate = gps.get(i).getCoordinate();
            String[] split = coordinate.split(",");
            for (int i1 = 0; i1 < split.length; i1++) {
                if (i1 % 2 == 0 || i1 == 0) {
                    trajectory.setX(Double.valueOf(split[i1]));
                } else {
                    trajectory.setY(Double.valueOf(split[i1]));
                }
            }
            trajectoryList.add(trajectory);
        }
        paramMap.put("tracks", trajectoryList);
        return paramMap;
    }

    public static long StringToTimestamp(String time, String format) {
        LocalDateTime parse1 = LocalDateTime.parse(time, DateTimeFormatter.ofPattern(format));
        ZoneId zone = ZoneId.systemDefault();

        Instant instant = parse1.atZone(zone).toInstant();
        Long l = instant.toEpochMilli();
        String s = l.toString();
        String sub = StrUtil.sub(s, 0, -3);
        return Long.parseLong(sub);
    }


}
